Vill du förbättra det här inlägget? Ge detaljerade svar på denna fråga, inklusive citat och en förklaring till varför ditt svar är korrekt. Svar utan tillräcklig detalj kan redigeras eller raderas. Jag har felaktigt lagt till filer i Git med kommandot: git lägg till myfile.txt Jag har ännu inte kört git commit. Finns det ett sätt att ångra detta, så att dessa filer inte ingår i åtagandet?
2020-12-07 21:21:22
1 2 Nästa Du kan ångra git-tillägg innan du begår med git resetsom tar bort det från det aktuella indexet (listan "om att bli förpliktad") utan att ändra något annat. Du kan använda git reset utan något filnamn för att avinstallera alla ändringar. Detta kan vara till nytta när det finns för många filer för att listas en efter en på en rimlig tid. I gamla versioner av Git motsvarar ovanstående kommandon git reset HEAD respektive git reset HEAD respektive kommer att misslyckas om HEAD är odefinierad (eftersom du ännu inte har gjort några åtaganden i ditt arkiv) eller tvetydig (eftersom du skapade en gren som heter HEAD, vilket är en dum sak som du inte borde göra). Detta ändrades dock i Git 1.8.2, så i moderna versioner av Git kan du använda kommandona ovan även innan du gör ditt första åtagande: "git reset" (utan alternativ eller parametrar) som används för att fel när du har inga förbindelser i din historia, men det ger dig nu ett tomt index (för att matcha obefintligt engagemang är du inte ens på). Dokumentation: git reset | Du vill: git rm --cached Resonemang: När jag var ny på detta försökte jag först git reset. (för att ångra hela mitt ursprungliga tillägg), bara för att få detta (inte så) hjälpsamma meddelande: dödlig: Det gick inte att lösa 'HEAD' som en giltig ref. Det visar sig att detta beror på att HEAD-ref (filial?) Inte existerar förrän efter den första förpliktelsen. Det vill säga, du kommer att stöta på samma nybörjarproblem som jag om ditt arbetsflöde, som mitt, var ungefär som: cd till min fantastiska nya projektkatalog för att prova Git, den nya hetheten git init git add. git-status ... massor av skit rullar av ... => Fan, jag ville inte lägga till allt detta. google "ångra git-tillägg" => hitta Stack Overflow - yay git reset. => dödlig: Det gick inte att lösa 'HEAD' som en giltig ref. Det visar sig vidare att det finns en bugg loggad mot att det inte är till nytta i e-postlistan. Och att den rätta lösningen var rätt där i Git-statusutgången (som, ja, jag glansade över som 'skit) ... # Ändringar som ska göras: # (använd "git rm --cached ..." för att ta bort scenen) ... Och lösningen är verkligen att använda git rm -cached FILE. Observera varningarna någon annanstans här - git rm raderar din lokala arbetskopia av filen, men inte om du använder --cached. Här är resultatet av git help rm: --cache Använd det här alternativet för att ta bort scener och ta bort sökvägar endast från indexet. Arbetande trädfiler, oavsett om de är modifierade eller inte, kommer att finnas kvar. Jag fortsätter att använda git rm --cached. för att ta bort allt och börja om. Fungerade dock inte, för samtidigt lägga till. är rekursiv, visar sig att rm behöver -r för att återgå. Suck. git rm -r --cached. Okej, nu är jag tillbaka till där jag började. Nästa gång ska jag använda -n för att göra en torr körning och se vad som kommer att läggas till: git add -n. Jag zippade upp allt till ett säkert ställe innan jag litade på git help rm om --cachen inte förstörde någonting (och tänk om jag stavade det fel). | Om du skriver: git-status Git kommer att berätta vad som är iscensatt, etc., inklusive instruktioner om hur man avbryter scenen: använd "git reset HEAD ..." för att avaktivera scenen Jag tycker att Git gör ett ganska bra jobb med att knuffa mig för att göra rätt i situationer som denna. Obs! Senaste Git-versioner (1.8.4.x) har ändrat detta meddelande: (använd "git rm --cached ..." för att ta bort scenen) | För att klargöra: git add flyttar ändringar från den aktuella arbetskatalogen till iscensättningsområdet (index). Denna process kallas iscensättning. Så det mest naturliga kommandot för att iscensätta ändringarna (ändrade filer) är det självklara: git-scenen git add är bara ett enklare alias för git-scenen Synd att det inte finns några git unstage eller git unadd-kommandon. Den relevanta är svårare att gissa eller komma ihåg, men det är ganska uppenbart: git reset HEAD - Vi kan enkelt skapa ett alias för detta: git config --global alias.unadd 'reset HEAD -' git config --global alias.unstage 'reset HEAD -' Och slutligen har vi nya kommandon: git lägg till fil 1 git scenfil2 git unadd-fil2 git unstage-fil1 Personligen använder jag ännu kortare alias: git a # för iscensättning git u # För avstegning | Ett tillägg till det accepterade svaret, om din felaktigt tillagda fil var enorm, kommer du förmodligen att märka att även efter att du har tagit bort den från index med 'git reset' verkar den fortfarande uppta plats i .git-katalogen. Det här är inget att oroa sig för; filen finns verkligen fortfarande i förvaret, men bara som ett "löst objekt". Det kommer inte att kopieras till andra förvar (via klon, push), och utrymmet kommer så småningom att återvinnas - men kanske inte så snart. Om du är orolig kan du springa: git gc - beskära = nu Uppdatering (det följande är mitt försök att rensa en viss förvirring som kan uppstå på grund av de mest röstade svaren): Så, vilket är det verkliga ångra av git add? git reset HEAD ? eller git rm --cached ? Strikt taget, och om jag inte tar fel: ingen. git add kan inte ångras - säkert, i allmänhet. Låt oss först komma ihåg vad git add faktiskt gör: Om inte spårades tidigare lägger git add till detcachen med dess nuvarande innehåll. Om redan spårades sparar git add det aktuella innehållet (ögonblicksbild, version) i cachen. I Git kallas den här åtgärden fortfarande add (inte bara uppdatera den), eftersom två olika versioner (snapshots) av en fil betraktas som två olika objekt: därför lägger vi verkligen till ett nytt objekt i cachen, för att så småningom begått senare. Mot bakgrund av detta är frågan lite tvetydig: Jag lade felaktigt till filer med kommandot ... OP: s scenario verkar vara det första (ospårad fil), vi vill att "ångra" tar bort filen (inte bara det aktuella innehållet) från de spårade objekten. Om så är fallet är det ok att köra git rm --cached . Och vi kan också köra git reset HEAD . Detta är i allmänhet att föredra, eftersom det fungerar i båda scenarierna: det gör också ångra när vi felaktigt lagt till en version av ett redan spårat objekt. Men det finns två försiktighetsåtgärder. Först: Det finns (som påpekades i svaret) bara ett scenario där git reset HEAD inte fungerar, men git rm --cached gör: ett nytt arkiv (ingen förpliktelser). Men egentligen är detta ett praktiskt taget irrelevant fall. För det andra: Var medveten om att git reset HEAD inte kan återställa det tidigare cachade filinnehållet på ett magiskt sätt, det synkroniserar det bara från HEAD. Om vårt felaktiga git-tillägg skrivit över en tidigare iscensatt, icke-åtagande version kan vi inte återställa den. Därför kan vi strängt taget inte ångra [*]. Exempel: $ git init $ echo "version 1"> file.txt $ git lägg till fil.txt # Första lägg till fil.txt $ git commit -m 'first commit' $ echo "version 2"> file.txt $ git lägg till file.txt # Stage (begå inte) "version 2" av file.txt $ git diff - cached file.txt -version 1 + version 2 $ echo "version 3"> file.txt $ git diff file.txt -version 2 + version 3 $ git add file.txt # Hoppsan menade vi inte det här $ git återställ HEAD file.txt # Ångra? $ git diff --cached file.txt # Naturligtvis ingen skillnad. scen == HEAD $ git diff file.txt # Vi har oåterkalleligt förlorat "version 2" -version 1 + version 3 Naturligtvis är detta inte särskilt viktigt om vi bara följer det vanliga lata arbetsflödet att göra 'git add' bara för att lägga till nya filer (fall 1), och vi uppdaterar nytt innehåll via kommittén commit, git commit -a. * (Redigera: ovanstående är praktiskt taget korrekt, men ändå kan det finnas några lite hackiga / invecklade sätt att återställa förändringar som iscensattes, men inte begåtts och sedan skrivits över - se kommentarerna från Johannes Matokic och iolsmit) | Ångra en fil som redan har lagts till är ganska lätt med Git. För att återställa myfile.txt, som redan har lagts till, använd: git reset HEAD myfile.txt Förklaring: När du har iscensatt oönskade filer för att ångra kan du göra git reset. Head är chef för din fil i den lokala och den sista parametern är namnet på din fil. Jag har skapat stegen i bilden nedan i mer detaljer för dig, inklusive alla steg som kan hända i dessa fall: | git rm --cached. -r kommer att "avinstallera" allt du har lagt till från din nuvarande katalog rekursivt | Springa git gui och ta bort alla filer manuellt eller genom att markera alla och klicka på unstage from commit-knappen. | Frågan ställs inte tydligt. Anledningen är att git add har två betydelser: lägga till en ny fil i iscensättningsområdet och ångra sedan med git rm -cached-fil. lägga till en modifierad fil till iscensättningsområdet och ångra sedan med git reset HEAD-fil. Om du är osäker, använd git återställ HEAD-fil Eftersom det gör det förväntade i båda fallen. Varning: om du gör git rm -cached-fil på en fil som har ändrats (en fil som fanns tidigare i förvaret), kommer filen att tas bort vid git commit! Det kommer fortfarande att finnas i ditt filsystem, men om någon annan gör ditt engagemang kommer filen att raderas från sitt arbetsträd. git-status kommer att berätta om filen var en ny fil eller modifierad: På filialmästaren Ändringar som ska göras: (använd "git reset HEAD ..." för att ta bort scenen) ny fil: my_new_file.txt modifierad: my_modified_file.txt | Git har kommandon för varje tänkbar åtgärd, men den behöver omfattande kunskap för att få saker rätt och därför är det i bästa fall kontraintuitivt ... Vad du gjorde tidigare: Ändrade en fil och använde git add., Eller git add . Vad du vill: Ta bort filen från indexet, men behåll den versionen och lämna den med otillåtna ändringar i arbetskopia: git reset HEAD Återställ filen till det senaste tillståndet från HEAD, ångra ändringar och ta bort dem från indexet: # Tänk `svn återställ ` IIRC. git reset HEAD git kassan # Om du har en " " med namnet " ", använd: git checkout - Detta behövs eftersom git reset - hård HEAD fungerar inte med enstaka filer. Ta bort från index och versionering och behåll den oversionerade filen med ändringar i arbetskopia: git rm --cached Ta bort från arbetskopia och versionering helt: git rm | Om du är på ditt första engagemang och du inte kan använda gitåterställ, förklara bara "Git konkurs" och ta bort .git-mappen och börja om | Enligt många av de andra svaren kan du använda git reset MEN: Jag hittade det här stora lilla inlägget som faktiskt lägger till Git-kommandot (ja, ett alias) för git unadd: se git unadd för detaljer eller .. Helt enkelt, git config --global alias.unadd "reset HEAD" Nu kan du git unadd foo.txt bar.txt | Använd git add -i för att ta bort just tillagda filer från ditt kommande engagemang. Exempel: Lägga till filen du inte ville ha: $ git lägg till foo $ git-status # På filialmästare # Ändringar som ska göras: # (använd "git reset HEAD ..." för att ta bort scenen) # # ny fil: foo # # Ospårade filer: # (använd "git add ..." för att inkludera i vad som kommer att göras) # [...] # Gå in i interaktiv läggning för att ångra din läggning (kommandona som skrivs vid git här är "r" (återställning), "1" (första posten i listan återgår visar), "återvänd" för att avbryta återställningsläge och "q" (sluta med): $ git add -i iscensatt ostadierad väg 1: + 1 / -0 ingenting foo *** Kommandon *** 1: [s] tatus 2: [u] pdate 3: [r] evert 4: [a] dd untracked 5: [p] atch 6: [d] iff 7: [q] uit 8: [h] elp Vad nu> r iscensatt ostadierad väg 1: + 1 / -0 ingenting [f] oo Återställ >> 1 iscensatt ostadierad väg * 1: + 1 / -0 ingenting [f] oo Återställ >> Obs: foo är inte spårad nu. återvände en väg *** Kommandon *** 1: [s] tatus 2: [u] pdate 3: [r] evert 4: [a] dd untracked 5: [p] atch 6: [d] iff 7: [q] uit 8: [h] elp Vad nu> q Hejdå. $ Det är allt! Här är ditt bevis som visar att "foo" är tillbaka på listan utan spårning: $ git-status # På filialmästare # Ospårade filer: # (använd "git add ..." för att inkludera i vad som kommer att göras) # [...] # foo ingenting läggs till för att begå men ospårade filer närvarande (använd "git add" för att spåra) $ | git remove eller git rm kan användas för detta med flaggan --cached. Prova: git hjälp rm | Här är ett sätt att undvika detta irriterande problem när du startar ett nytt projekt: Skapa huvudkatalogen för ditt nya projekt. Kör git init. Skapa nu en .gitignore-fil (även om den är tom). Begå din .gitignore-fil. Git gör det väldigt svårt att göra git reset om du inte har några åtaganden. Om du skapar en liten initial förpliktelse bara för att ha en, efter det kan du git add -A och git reset så många gånger du vill för att få allt rätt. En annan fördel med den här metoden är att om du stöter på radavslutsproblem senare och behöver uppdatera alla dina filer är det enkelt: Kolla in det första åtagandet. Detta tar bort alla dina filer. Kolla sedan in ditt senaste åtagande igen. Detta kommer att hämta nya kopior av dina filer med dina nuvarande inställningar för radslut. | Kanske har Git utvecklats sedan du skickade din fråga. $> git --version git version 1.6.2.1 Nu kan du försöka: git reset HEAD. Detta borde vara vad du letar efter. | Observera att om du inte anger en revision måste du inkludera en separator. Exempel från min konsol: git reset fatal: tvetydigt argument ' ': okänd revision eller sökväg inte i arbetsträdet. Använd '-' för att skilja vägar från versioner git reset - Ostadierade ändringar efter återställning: M (Git version 1.7.5.4) | Så här tar du bort nya filer från iscensättningsområdet (och endast om en ny fil): git rm --cached FILE Använd rm --cached endast för nya filer som av misstag har lagts till. | För att återställa varje fil i en viss mapp (och dess undermappar) kan du använda följande kommando: git reset * | Använd kommandot * för att hantera flera filer åt gången: git reset HEAD * .prj git reset HEAD * .bmp git reset HEAD * gdb * etc. | Skriv bara git reset, det kommer att återgå och det är som om du aldrig skrev git add. sedan ditt senaste åtagande. Se till att du har begått tidigare. | Antag att jag skapar en ny fil, newFile.txt: Antag att jag av misstag lägger till filen, git add newFile.txt: Nu vill jag ångra det här tillägget, innan begå, git återställ newFile.txt: | För en specifik fil: git återställ my_file.txt git kassan my_file.txt För alla tillagda filer: git reset. git kassan. Obs: kassan ändrar koden i filerna och flyttar till det senast uppdaterade (engagerade) tillståndet. återställning ändrar inte koder; det återställer bara rubriken. | För att ångra git-tillägg, använd: git återställ filnamn | Detta kommando tar bort dina ändringar: git återställ HEAD filnamn.txt Du kan också använda git add -p för att lägga till delar av filer. | Det finns också interaktivt läge: git add -i Välj alternativ 3 för att ta bort filer. I mitt fall vill jag ofta lägga till mer än en fil, och med interaktivt läge kan du använda siffror som detta för att lägga till filer. Detta tar alla utom 4: 1, 2, 3 och 5 För att välja en sekvens, skriv bara 1-5 för att ta allt från 1 till 5. Git iscensättningsfiler | git add myfile.txt # Detta lägger till din fil i listan som ska göras Helt motsatsen till detta kommando är, git reset HEAD myfile.txt # Detta kommer att ångrasDet. så kommer du att vara i det tidigare tillståndet. Specificerad kommer att återkomma i ospårad lista (föregående tillstånd). Det kommer att återställa ditt huvud med den angivna filen. så om ditt huvud inte har det betyder det helt enkelt att återställa det. | git återställ filnamn.txt Tar bort en fil med namnet filnamn.txt från det aktuella indexet, området "på väg att begås", utan att ändra något annat. | git återställ filnamn.txt Tar bort en fil med namnet filename.txt från det aktuella indexet, området "på väg att åta sig", utan att ändra något annat. | I Sourcetree kan du göra det enkelt via GUI. Du kan kontrollera vilket kommando Sourcetree använder för att avinstallera en fil. Jag skapade en ny fil och lade till den i Git. Sedan avstängde jag det med Sourcetree GUI. Detta är resultatet: Avstängning av filer [08/12/15 10:43] git -c diff.mnemonicprefix = false -c core.quotepath = false -c credential.helper = sourcetree reset -q - sökväg / till / fil / filnamn.java Sourcetree använder reset för att avinstallera nya filer. | 1 2 Nästa Mycket aktiv fråga. Tjäna 10 rykte för att svara på den här frågan. Kravet på rykte hjälper till att skydda denna fråga från skräppost och icke-svar-aktivitet. Inte svaret du letar efter? Bläddra bland andra frågor taggade git version-control git-commit git-stage eller ställ din egen fråga.